package com.cerosoft;

import java.io.File;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;

import com.cerosoft.api.exceptions.ConnectionException;
import com.cerosoft.api.http.models.MediaInfo;
import com.cerosoft.api.http.webservices.MediaBrowserWebServiceProxy;
import com.cerosoft.google.api.GoogleAccount;
import com.cerosoft.google.api.GoogleContacts;
import com.cerosoft.google.api.GoogleServiceException;
import com.cerosoft.handler.HandlerDispatcher;
import com.cerosoft.handler.IMediaHandler;
import com.cerosoft.utils.AbstractCacheAdapter;

public class MediaMain extends Activity implements OnClickListener,
		OnItemClickListener {

	private volatile boolean isGoogleLogin = false;

	private int errorMsg = -1;

	private int root = 0;

	private void rootAdd() {
		root++;
	}

	private void rootSub() {
		root--;
	}

	private GridView gv = null;

	private CacheAdapter adapter = null;

	private String ipAddr = null;

	private EditText userTxt = null;

	private EditText pwdTxt = null;

	private TextView topBar = null;

	private TextView errView = null;

	private View initLoginView() {
		View view = View.inflate(this, R.layout.google_login, null);
		errView = (TextView) view.findViewById(R.id.err_txt);
		userTxt = (EditText) view.findViewById(R.id.user_text);
		pwdTxt = (EditText) view.findViewById(R.id.pwd_text);

		if (errorMsg != -1) {
			errView.setVisibility(View.VISIBLE);
			errView.setText(errorMsg);
		} else {
			errView.setVisibility(View.GONE);
		}
		return view;
	}

	private void updateUI() {
		if (adapter != null) {
			adapter.notifyDataSetChanged();
		}
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();
		if (t != null && t.isAlive()) {
			t.interrupt();
		}
	}

	private void test() {
		// ipAddr = "http://192.168.10.104:8080";
		ipAddr = "http://192.168.1.50:8080";
		try {
			init();
		} catch (ConnectionException e) {
			e.printStackTrace();
		}
	}

	private void loginPage() {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(R.string.login);
		builder.setView(initLoginView());
		builder.setPositiveButton(R.string.login,
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						login(userTxt.getText().toString(), pwdTxt.getText()
								.toString());
					}
				});
		builder.setNegativeButton(R.string.dlg_cancel,
				new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						finish();
					}
				});

		AlertDialog dlg = builder.create();
		dlg.show();
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.main);

		ImageView btn = (ImageView) findViewById(R.id.backbtn);
		btn.setOnClickListener(this);

		topBar = (TextView) findViewById(R.id.result_txt);

		gv = (GridView) findViewById(R.id.gride);

		adapter = new CacheAdapter(this);
		gv.setAdapter(adapter);

		gv.setOnItemClickListener(this);

		isGoogleLogin = false;
		errorMsg = -1;

		loginPage();
		// test();
	}

	private Thread t = null;

	private void login(final String userName, final String pwd) {
		final ProgressDialog pd = ProgressDialog.show(this, getResources()
				.getText(R.string.loading_title),
				getResources().getText(R.string.loading_content));

		t = new Thread() {
			public void run() {
				GoogleAccount account = new GoogleAccount(userName, pwd);
				String auth = null;
				try {
					auth = account.loginGoogle();
					GoogleContacts contacts = new GoogleContacts(account);
					ipAddr = contacts.getContact("HomeMediaServer");
					Log.i("ip", "the ip address = " + ipAddr);
					init();
					isGoogleLogin = true;
					gv.post(new Runnable() {

						@Override
						public void run() {
							updateUI();
						}
					});
				} catch (GoogleServiceException e) {
					isGoogleLogin = false;
					errorMsg = R.string.err_msg_bad_authentication;
				} catch (ConnectionException e) {
					isGoogleLogin = false;
					errorMsg = R.string.err_msg_bad_server;
				}
				pd.dismiss();

				if (!isGoogleLogin) {
					gv.post(new Runnable() {

						@Override
						public void run() {
							loginPage();
						}
					});
				}
			}
		};

		t.start();
	}

	List<MediaInfo> folders = null;

	private void init() throws ConnectionException {
		folders = MediaBrowserWebServiceProxy.getInstance().getFolderList(
				ipAddr);
		Log.d("test", "size=" + folders.size());

		topBar.post(new Runnable() {

			@Override
			public void run() {
				topBar.setText(R.string.root_str);
			}
		});
	}

	private class CacheAdapter extends AbstractCacheAdapter<MediaInfo> {

		public CacheAdapter(Context c) {
			super(c);
		}

		@Override
		public int getCount() {
			if (folders != null) {
				return folders.size();
			}
			return 0;
		}

		@Override
		public Object getItem(int position) {
			return folders == null ? null : folders.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		protected View initConvertView(final int position) {

			MediaInfo mediaInfo = folders.get(position);

			View itemView = View.inflate(MediaMain.this, R.layout.itemview,
					null);
			TextView tv = (TextView) itemView.findViewById(R.id.itemname);
			tv.setText(mediaInfo.getName());
			ImageView iv = (ImageView) itemView.findViewById(R.id.showupimg);

			switch (mediaInfo.getMediaType()) {
			case folder: {
				iv.setImageResource(R.drawable.folder);
				break;
			}
			case file: {
				if (mediaInfo.getFileType() == null) {
					iv.setImageResource(R.drawable.file);
					break;
				}
				switch (mediaInfo.getFileType()) {
				case image:
				case audio:
				case video: {
					new AsyncLoadImage().execute(new Object[] { iv,
							folders.get(position).getPath() });
					break;
				}
				default: {
					iv.setImageResource(R.drawable.file);
				}
				}
				break;
			}
			}

			return itemView;
		}

		class AsyncLoadImage extends AsyncTask<Object, Object, Void> {
			@Override
			protected Void doInBackground(Object... params) {

				ImageView imageView = (ImageView) params[0];
				String path = (String) params[1];
				Bitmap bitmap = MediaBrowserWebServiceProxy.getInstance()
						.getThumbnailViaURL(ipAddr, path);
				publishProgress(new Object[] { imageView, bitmap });
				return null;
			}

			protected void onProgressUpdate(Object... progress) {
				ImageView imageView = (ImageView) progress[0];
				if (imageView == null) {
					Log.e("test", "onProgressUpdate no imageview");
					return;
				}
				if (progress[1] == null) {
					Log.e("test", "onProgressUpdate progress[1]==null");
					imageView.setImageResource(R.drawable.file);
				} else {
					Log.i("test", "onProgressUpdate got bitmap");
					imageView.setImageBitmap((Bitmap) progress[1]);
				}
			}
		}

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.backbtn: {
			rootSub();

			try {
				if (backToHome()) {
					System.exit(0);
				} else if (isRoot()) {
					folders = MediaBrowserWebServiceProxy.getInstance()
							.getFolderList(ipAddr);
					topBar.setText(R.string.root_str);
				} else if (folders != null && folders.size() >= 0) {
					String parentPath = topBar.getText().toString();
					parentPath = parentPath.substring(0,
							parentPath.lastIndexOf(File.separator));
					topBar.setText(parentPath);
					Log.d("m", "onClick parentPath=" + parentPath);
					folders = MediaBrowserWebServiceProxy.getInstance()
							.getFolderInfo(ipAddr, parentPath);
				}
			} catch (ConnectionException e) {
				timeoutAndRelogin();
			}
			adapter.notifyDataSetChanged();
			break;
		}
		}
	}

	private boolean isRoot() {
		return root == 0;
	}

	private boolean backToHome() {
		return root < 0;
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		Log.d("test", "arg2=" + arg2);
		MediaInfo info = folders.get(arg2);

		Log.d("m", "onItemClick parentPath=" + info.getParentPath());
		Log.d("m", "onItemClick path=" + info.getPath());
		switch (info.getMediaType()) {
		case folder: {
			rootAdd();
			try {
				folders = MediaBrowserWebServiceProxy.getInstance()
						.getFolderInfo(ipAddr, info.getPath());
			} catch (ConnectionException e) {
				timeoutAndRelogin();
			}
			if (adapter != null) {
				adapter.notifyDataSetChanged();
			}
			topBar.setText(info.getPath());
			break;
		}
		case file: {

			IMediaHandler handler = HandlerDispatcher.dispatch(info);

			String[] medias = HandlerDispatcher.getStringArrayByType(folders,
					info.getFileType());

			if (handler != null) {
				handler.handling(MediaMain.this, ipAddr, info.getPath(), medias);
			}

			break;
		}
		}

	}

	private void timeoutAndRelogin() {
		isGoogleLogin = false;
		errorMsg = R.string.err_msg_bad_server;
		gv.post(new Runnable() {

			@Override
			public void run() {
				loginPage();
			}
		});
	}
}